package co.edu.javeriana.touresbalon.oms.services;

import co.edu.javeriana.touresbalon.b2c.entities.Hotel;
import co.edu.javeriana.touresbalon.b2c.entities.Producto;
import co.edu.javeriana.touresbalon.oms.entities.Customer;
import co.edu.javeriana.touresbalon.oms.entities.Items;
import co.edu.javeriana.touresbalon.oms.entities.ItemsPK;
import co.edu.javeriana.touresbalon.oms.entities.Orders;
import co.edu.javeriana.touresbalon.oms.enumerations.OrderProcessState;
import co.edu.javeriana.touresbalon.oms.enumerations.OrderState;
import co.edu.javeriana.touresbalon.oms.webservices.clients.bpel.WSBPELClient;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

/**
 *
 * @author ada
 */
@Stateless
public class OrdersBeanService implements OrdersBeanLocal {

    private static final String QUERY_UPDATE_ORDERS_FROM_PROCESS = "update ORDERS set COMMENTS=?, REFRESH_DATE=?, STATUS=?, PROCESS_STATUS=? where ORDERID=?";
    private static final String OBTAIN_LAST_ID = "select MAX(ORDERID) from ORDERS";
    @PersistenceContext(unitName = "TouresBalon_OMS-ejbPU")
    EntityManager manager;
    @EJB
    private EspectaculosBeanServiceLocal espectaculosBeanServiceLocal;

    @Override
    public void updateOrderFromProcess(String comments, Date refreshDate, String status, String processStatus, String orderId) {
        Query query = manager.createNativeQuery(QUERY_UPDATE_ORDERS_FROM_PROCESS);
        query.setParameter(1, comments);
        query.setParameter(2, refreshDate);
        query.setParameter(3, status);
        query.setParameter(4, processStatus);
        query.setParameter(5, orderId);
        query.executeUpdate();
    }

    @Override
    public void createOrderFromB2C(Orders newOrder, Producto newProduct) {
        //Se crea producto
        int idHotel = (int) Math.floor(Math.random() * 10);
        newProduct.getIdHotel().setIdHotel(idHotel);
        Hotel newHotel=newProduct.getIdHotel();
        newHotel.setIdHotel(idHotel+1);
        newHotel.getHabitacionesList().get(0).setIdHabitacion(newHotel.getHabitacionesList().get(0).getIdHabitacion()+1);
        newProduct.getTransporteCollection().get(0).setIdTransporte(idHotel);
        newProduct.getIdHotel().getHabitacionesList().get(0).setIdHotel(newHotel);
        newProduct.setIdProducto(idHotel);
        espectaculosBeanServiceLocal.ingresarProducto(newProduct);        
//        Integer idProduct = espectaculosBeanServiceLocal.obtenerIdUltimoProductoIngresado();
        Integer idProduct=idHotel;
        if (idProduct != -1) {
            newProduct.setIdProducto(idProduct);
            //Se crea orden
            newOrder.setStatus(OrderState.EN_VALIDACION.name());
            newOrder.setProcessStatus(OrderProcessState.OK.name());
            if (newOrder.getItemsList() == null) {
                List<Items> item = new ArrayList<Items>();
                item.add(new Items());
                newOrder.setItemsList(item);
            }
            newOrder.getItemsList().get(0).setProductid(BigInteger.valueOf(idProduct));
            newOrder.getItemsList().get(0).setItemsPK(new ItemsPK(idProduct + "", newOrder.getOrderid()));
            newOrder.getItemsList().get(0).setPrice(newOrder.getPrice());
            newOrder.getItemsList().get(0).setQuantity(1);
            ingresarOrder(newOrder);
            String idOrden = this.obtenerIdUltimaOrdenIngresada();
            if (idOrden != null) {
                newOrder.setOrderid(idOrden);
                //Se arranca proceso BPEL reserva de orden
                WSBPELClient wsBPELClient = new WSBPELClient();
                wsBPELClient.callOrderProcess(newOrder, newProduct);
            }
        }
    }

    @TransactionAttribute(TransactionAttributeType.NEVER)
    private void ingresarOrder(Orders newOrder) {
        manager.persist(newOrder);
        manager.flush();
    }

    @Override
    public List<Orders> findOrdersByCustomer(String idCustomer) {
        Query query = manager.createNamedQuery("Customer.findByCustid");
        query.setParameter("custid", idCustomer);
        try {
            Customer foundCustomer = (Customer) query.getSingleResult();
            foundCustomer.getOrdersList().size();
            List<Orders> foundOrders = new ArrayList<Orders>();
            for (Orders orden : foundCustomer.getOrdersList()) {
                if (orden.getProcessStatus().equalsIgnoreCase(OrderProcessState.OK.name())) {
                    foundOrders.add(orden);
                }
            }
            return foundOrders;
        } catch (NoResultException ex) {
            return new ArrayList<Orders>();
        }
    }

    @Override
    public List<Orders> findOrdersByState(String state) {
        Query query = manager.createNamedQuery("Orders.findByStatus");
        query.setParameter("status", state);
        List<Orders> foundOrders = query.getResultList();
        if (foundOrders == null) {
            foundOrders = new ArrayList<Orders>();
        }
        return foundOrders;
    }

    @Override
    public List<Orders> findOrdersByProcessState(String processState) {
        Query query = manager.createNamedQuery("Orders.findByProcessStatus");
        query.setParameter("processStatus", processState);
        List<Orders> foundOrders = query.getResultList();
        if (foundOrders == null) {
            foundOrders = new ArrayList<Orders>();
        }
        return foundOrders;
    }

    @Override
    public List<Orders> findOrdersByStateAndProcessState(String state, String processState) {
        Query query = manager.createNamedQuery("Orders.findByStatusAndProcessStatus");
        query.setParameter("processStatus", processState);
        query.setParameter("status", state);
        List<Orders> foundOrders = query.getResultList();
        if (foundOrders == null) {
            foundOrders = new ArrayList<Orders>();
        }
        return foundOrders;
    }

    private String obtenerIdUltimaOrdenIngresada() {
        Query query = manager.createNativeQuery(OBTAIN_LAST_ID);
        try {
            String id = (String) query.getSingleResult();
            return id;
        } catch (NoResultException e) {
            return null;
        }
    }
}
